View Javadoc
1 /* 2 * Angkor Web Framework 3 * 4 * Distributable under LGPL license. 5 * See terms of license at gnu.org. 6 */ 7 8 package com.tirsen.angkor.beans; 9 10 import com.tirsen.angkor.table.AbstractTableModel; 11 import com.tirsen.angkor.widget.ValueModel; 12 13 import java.beans.BeanInfo; 14 import java.beans.IntrospectionException; 15 import java.beans.Introspector; 16 import java.beans.PropertyDescriptor; 17 import java.io.Serializable; 18 import java.util.ArrayList; 19 import java.util.Arrays; 20 import java.util.Collection; 21 import java.util.Iterator; 22 import java.util.List; 23 24 public class JavaBeanTableModel extends AbstractTableModel 25 { 26 private Class rowClass; 27 private List rows; 28 private List columns; 29 30 public JavaBeanTableModel() 31 { 32 } 33 34 public JavaBeanTableModel(Class rowClass) 35 { 36 this.rowClass = rowClass; 37 } 38 39 public interface TableColumnModel extends Serializable 40 { 41 String getName(); 42 43 ValueModel getValue(Object row); 44 } 45 46 private static class PropertyTableColumnModel implements TableColumnModel 47 { 48 private String name; 49 private transient PropertyDescriptor property; 50 51 public PropertyTableColumnModel(PropertyDescriptor property) 52 { 53 this.property = property; 54 } 55 56 public PropertyTableColumnModel(String name, PropertyDescriptor property) 57 { 58 this.name = name; 59 this.property = property; 60 } 61 62 public String getName() 63 { 64 return name == null ? property.getDisplayName() : name; 65 } 66 67 public ValueModel getValue(Object row) 68 { 69 return new PropertyValueModel(row, property); 70 } 71 } 72 73 /*** 74 * Resets the columns. 75 */ 76 public void resetColumns() 77 { 78 columns = null; 79 } 80 81 /*** 82 * If the columns are not already created creates columns based on all the properties in the beans. 83 */ 84 private void createDefaultColumns() 85 { 86 if (columns == null) 87 { 88 try 89 { 90 PropertyDescriptor[] properties = getProperties(); 91 columns = new ArrayList(properties.length); 92 for (int i = 0; i < properties.length; i++) 93 { 94 PropertyDescriptor property = properties[i]; 95 addColumn(new PropertyTableColumnModel(property)); 96 } 97 } 98 catch (IntrospectionException e) 99 { 100 throw new RuntimeException(e.getMessage()); 101 } 102 } 103 } 104 105 private PropertyDescriptor[] getProperties() throws IntrospectionException 106 { 107 Class beanClass = getRowClass(); 108 BeanInfo beanInfo = Introspector.getBeanInfo(beanClass, Object.class); 109 PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors(); 110 return properties; 111 } 112 113 private Class getRowClass() 114 { 115 Class cls = rowClass; 116 if (cls == null && getRowCount() > 0) cls = getRow(0).getClass(); 117 if (cls == null) cls = getRows().getClass().getComponentType(); 118 if (cls == null) throw new IllegalStateException("Could not determine class of objects used for rows."); 119 return cls; 120 } 121 122 public void addColumn(TableColumnModel column) 123 { 124 columns.add(column); 125 } 126 127 public PropertyDescriptor findProperty(String property) 128 { 129 try 130 { 131 PropertyDescriptor[] properties = getProperties(); 132 for (int i = 0; i < properties.length; i++) 133 { 134 PropertyDescriptor propertyDesc = properties[i]; 135 if (propertyDesc.getName().equals(property)) return propertyDesc; 136 } 137 throw new IntrospectionException("No such property " + property); 138 } 139 catch (IntrospectionException e) 140 { 141 throw new RuntimeException(e.getMessage()); 142 } 143 } 144 145 public void addColumn(String name, String property) 146 { 147 if (columns == null) columns = new ArrayList(1); 148 columns.add(new PropertyTableColumnModel(name, findProperty(property))); 149 } 150 151 public String getColumnName(int column) 152 { 153 return getColumn(column).getName(); 154 } 155 156 public int getColumnCount() 157 { 158 createDefaultColumns(); 159 return columns.size(); 160 } 161 162 public ValueModel getValueAt(int row, int column) 163 { 164 return (getColumn(column)).getValue(getRow(row)); 165 } 166 167 private TableColumnModel getColumn(int column) 168 { 169 createDefaultColumns(); 170 return (TableColumnModel) columns.get(column); 171 } 172 173 /*** 174 * Gets the value object for a specified row, also checks wheather row is within range specified by 175 * {@link #setRange(int,int)}. 176 * @throws IllegalArgumentException if <code>row</code> parameter is outside specified range. 177 */ 178 public Object getRow(int row) 179 { 180 if (row < getStart() || row > getEnd()) 181 { 182 throw new IllegalArgumentException("Tried to access row " + row + 183 " outside range (" + getStart() + ", " + getEnd() + ")."); 184 } 185 return getRows().get(row); 186 } 187 188 private List getRows() 189 { 190 if (rows == null) throw new IllegalStateException("Tried to access model before initializing rows."); 191 return rows; 192 } 193 194 public int getRowCount() 195 { 196 int rowCount = super.getRowCount(); 197 if (rowCount == -1) 198 { 199 if (rows == null) 200 rowCount = 0; 201 else 202 rowCount = getRows().size(); 203 } 204 return rowCount; 205 } 206 207 public void setRow(int row, Object object) 208 { 209 ensureCapable(row); 210 rows.set(row, object); 211 } 212 213 /*** 214 * Sets a segment of rows starting at specified startRow. 215 */ 216 public void setRows(int startRow, Collection objects) 217 { 218 ensureCapable(startRow + objects.size()); 219 int row = startRow; 220 for (Iterator iterator = objects.iterator(); iterator.hasNext();) 221 { 222 Object o = (Object) iterator.next(); 223 rows.set(row++, o); 224 } 225 } 226 227 private void ensureCapable(int row) 228 { 229 if (rows == null) rows = new ArrayList(row); 230 int size = rows.size(); 231 for (int i = size - row; i < size + 1; i++) 232 { 233 rows.add(null); 234 } 235 } 236 237 public void setRows(Object[] rows) 238 { 239 if (rows != null) 240 this.rows = Arrays.asList(rows); 241 else 242 this.rows = null; 243 } 244 245 public void setRows(List rows) 246 { 247 this.rows = new ArrayList(rows); 248 } 249 250 public void setRows(Iterator iterator) 251 { 252 rows = new ArrayList(); 253 while (iterator.hasNext()) 254 { 255 Object o = (Object) iterator.next(); 256 rows.add(o); 257 } 258 } 259 260 public void empty() 261 { 262 super.empty(); 263 rows = null; 264 } 265 }

This page was automatically generated by Maven